package cn.mrlong.tools.bean

import org.apache.commons.dbutils.*
import org.apache.commons.dbutils.handlers.BeanHandler
import org.apache.commons.dbutils.handlers.BeanListHandler
import org.apache.commons.dbutils.handlers.ColumnListHandler
import org.apache.commons.dbutils.handlers.ScalarHandler
import java.lang.reflect.ParameterizedType
import java.sql.Connection
import java.sql.SQLException

abstract class BaseDAO<T> {
    private val clazz: Class<T>
    protected var queryRunner: QueryRunner = QueryRunner()


    init {
        val clazzTemp: Class<*> = this.javaClass //获取子类的类型
        //获取父类的类型
        //getGenericSuperclass() 代表获取父类的类型
        //parameterizedType 代表的是带泛型的类型
        val parameterizedType = clazzTemp.genericSuperclass as ParameterizedType
        //获取泛型类型的数组
        val types = parameterizedType.actualTypeArguments
        this.clazz = types[0] as Class<T>
    }

    //除开增删改查. 还需要sql语句查询比如总共有多少个用户之类的通用方法
    fun <E> getValue(conn: Connection?, sql: String?, vararg args: Any?): E? {
        var result: E? = null
        val handler = ScalarHandler<E>()
        try {
            result = queryRunner.query(conn, sql, handler, *args)
        } catch (e: SQLException) {
            e.printStackTrace()
        }
        return result
    }


    //查询多个对象--ver3.0
    fun queryList(conn: Connection?, sql: String?, vararg objs: Any?): List<T>? {
        var list: List<T>? = null
        //开启驼峰映射 因为数据库是 create_time .而java 类是createTime
        val bean: BeanProcessor = GenerousBeanProcessor()
        val processor: RowProcessor = BasicRowProcessor(bean)
        val handler = BeanListHandler(clazz, processor)
        try {
            list = queryRunner.query(conn, sql, handler, *objs)
        } catch (e: SQLException) {
            e.printStackTrace()
        }
        return list
    }

    //List<Object>每个列数据类型不同
    fun queryTitleList(conn: Connection?, sql: String?, vararg objs: Any?): List<String?>? {
        var list: List<String?>? = null
        val handler = ColumnListHandler<String>("title")
        try {
            list = queryRunner.query(conn, sql, handler, *objs)
        } catch (e: SQLException) {
            e.printStackTrace()
        }
        return list
    }

    //List<Object>每个列数据类型不同
    fun queryImageRecords(conn: Connection?, sql: String?, vararg objs: Any?): List<String?>? {
        var list: List<String?>? = null
        val handler = ColumnListHandler<String>("image_records")
        try {
            list = queryRunner.query(conn, sql, handler, *objs)
        } catch (e: SQLException) {
            e.printStackTrace()
        }
        return list
    }


    //查询单个对象--ver3.0
    fun getBean(conn: Connection?, sql: String?, vararg objs: Any?): T? {
        var t: T? = null
        try {
            //开启驼峰映射
            val bean: BeanProcessor = GenerousBeanProcessor()
            val processor: RowProcessor = BasicRowProcessor(bean)
            t = queryRunner.query(conn, sql, BeanHandler(clazz, processor), *objs)
        } catch (e: SQLException) {
            e.printStackTrace()
        }
        return t
    }

    //增删改 通用--ver3.0
    fun update(conn: Connection?, sql: String?, vararg args: Any?): Int {
        var count = 0
        try {
            count = queryRunner.update(conn, sql, *args)
        } catch (e: SQLException) {
            e.printStackTrace()
        }
        return count
    }

    //修改多个对象的id;
    fun updateBatch(conn: Connection?, sql: String?, args: Array<Array<Any?>?>?) {
        try {
            queryRunner.batch(conn, sql, args)
        } catch (throwables: SQLException) {
            throwables.printStackTrace()
        }
    }
}
